﻿using System;
using System.Collections.Generic;

namespace MathExp
{
    public class Operator
    {
        private String name;
        public int PRI { get; set; }
        protected Operator(String name)
        {
            this.name = name;
        }
        public virtual int GetDimension() { return 0; }


        public virtual Object Eval(Object[] oprands, int offset, IDictionary<String, Decimal> symbolTable) { return 0; }

        public Object Eval(Object[] oprands, IDictionary<String, Decimal> symbolTable)
        {
            return Eval(oprands, 0,symbolTable);
        }

        protected Decimal GetDecimal(Object t, IDictionary<String, Decimal> symbolTable)
        {
            if (t is Decimal)
            {
                return Convert.ToDecimal(t);
            }

            if (t is String)
            {
                return Convert.ToDecimal(symbolTable[t.ToString()]);
            }
            return 0M;
        }

        public override string ToString()
        {
            return this.name;
        }

    }
    public class Plus : Operator
    {
        public Plus() : base("+") { PRI = 2; }
        public override int GetDimension()
        {
            return 2;
        }
        public override Object Eval(Object[] oprands, int offset,IDictionary<String, Decimal> symbolTable)
        {
            decimal a = this.GetDecimal(oprands[0], symbolTable);
            decimal b = this.GetDecimal(oprands[1], symbolTable);
            return a + b;
        }
    }
    public class Minus : Operator
    {
        public Minus() : base("-") { PRI = 2; }
        public override int GetDimension()
        {
            return 2;
        }
        public override Object Eval(Object[] oprands, int offset, IDictionary<String, Decimal> symbolTable)
        {
            decimal a = this.GetDecimal(oprands[0], symbolTable);
            decimal b = this.GetDecimal(oprands[1], symbolTable);
            return a - b;
        }
    }
    public class Multiple : Operator
    {
        public Multiple() : base("*") { PRI = 3; }
        public override int GetDimension()
        {
            return 2;
        }
        public override Object Eval(Object[] oprands, int offset, IDictionary<String, Decimal> symbolTable)
        {
            decimal a = this.GetDecimal(oprands[0], symbolTable);
            decimal b = this.GetDecimal(oprands[1], symbolTable);
            return a * b;
        }
    }
    public class Divide : Operator
    {
        public Divide() : base("/") { PRI = 3; }
        public override int GetDimension()
        {
            return 2;
        }
        public override Object Eval(Object[] oprands, int offset, IDictionary<String, Decimal> symbolTable)
        {
            decimal a = this.GetDecimal(oprands[0], symbolTable);
            decimal b = this.GetDecimal(oprands[1], symbolTable);
            return a / b;
        }
    }
    public class GreateThan : Operator
    {
        public GreateThan() : base(">") { PRI = 1; }
        public override int GetDimension()
        {
            return 2;
        }
        public override Object Eval(Object[] oprands, int offset, IDictionary<String, Decimal> symbolTable)
        {
            decimal a = this.GetDecimal(oprands[0], symbolTable);
            decimal b = this.GetDecimal(oprands[1], symbolTable);
            return a / b;
        }
    }
}
